
/**
 * function
 *
 * compute satellite position, velocity and relativity corrections.
 *
 * modified from ComputeSatPos 
 *
 * copyright(c)
 *
 * Shoujian zhang, 2020, Wuhan
 */


#ifndef ComputeSatPos_HPP
#define ComputeSatPos_HPP


#include "ProcessingClass.hpp"
#include "XvtStore.hpp"
#include "DataStructures.hpp"
#include "CommonHeader.hpp"

using namespace gpstk;

namespace gnssbox
{

      /** compute gnss satellite's relativity correction, satellite position and
       *  velocity at transmission time.
       *
       * A typical way to use this class follows:
       *
       * @code
       * 
       * @endcode
       *
       *
       */
    class ComputeSatPos : public ProcessingClass
    {
    public:

         /// Default constructor. Observable C1 will be used for computations
         /// and satellites with elevation less than 10 degrees will be
         /// deleted.
        ComputeSatPos()
            : pEphStore(NULL), 
              defaultObsOfGPS(TypeID::C1), useTGDOfGPS(false),
              defaultObsOfGAL(TypeID::C1), useTGDOfGAL(false),
              defaultObsOfBDS(TypeID::C2), useTGDOfBDS(false)
        {};


         /** Explicit constructor, ephemeris to be used and whether TGD will
          *  be computed or not.
          *
          * @param dEphemeris    EphemerisStore object to be used by default.
          * @param dObservable   Observable type to be used by default.
          * @param applyTGD      Whether or not C1 observable will be
          *                      corrected from TGD effect.
          *
          */
        ComputeSatPos( XvtStore<SatID>& ephStore,
                        const TypeID& dObsOfGPS = TypeID::C1,
                        const TypeID& dObsOfGAL = TypeID::C1,
                        const TypeID& dObsOfBDS = TypeID::C2,
                        const bool& applyTGDOfGPS = false,
                        const bool& applyTGDOfGAL = false,
                        const bool& applyTGDOfBDS = false );


         /** Return a satTypeValueMap object, adding the new data generated
          *  when calling a modeling object.
          *
          * @param time      Epoch.
          * @param gData     Data object holding the data.
          */
        virtual satTypeValueMap& Process(const CommonTime& time,
                                         const SourceID& source,
                                         satTypeValueMap& gData)
            noexcept(false);


         /** Return a gnssRinex object, adding the new data generated when
          *  calling a modeling object.
          *
          * @param gData    Data object holding the data.
          */
        virtual void Process(gnssRinex& gData)
            noexcept(false);


         /** Method to set the default observable for computations.
          *
          * @param type      TypeID object to be used by default
          */
        virtual ComputeSatPos& setDefaultObs( const TypeID& type,
                                               const SatelliteSystem& sys 
                                                     = SatelliteSystem::GPS )
        {
            if(sys == SatelliteSystem::GPS)
                defaultObsOfGPS = type;
            else if(sys == SatelliteSystem::Galileo)
                defaultObsOfGAL = type;
            else if(sys == SatelliteSystem::BDS)
                defaultObsOfBDS = type;

            return (*this);
        };


         /// Method to set use of TGD
        virtual ComputeSatPos& setUseTGD(bool tgd,
                                          const SatID::SatelliteSystem& sys 
                                                = SatelliteSystem::GPS)
        {
            if(sys == SatelliteSystem::GPS)
                useTGDOfGPS = tgd;
            else if(sys == SatelliteSystem::Galileo)
                useTGDOfGAL = tgd;
            else if(sys == SatelliteSystem::BDS)
                useTGDOfBDS = tgd;

            return (*this);
        };


         /** Method to set the default XvtStore<SatID> to be used with GNSS
          *  data structures.
          *
          * @param ephem     XvtStore<SatID> object to be used by default
          */
        virtual ComputeSatPos& setEphStore(XvtStore<SatID>& ephStore)
        { pEphStore = &ephStore; return (*this); };


        virtual Xvt ComputeAtTransmitTime(const CommonTime& tr,
                                          const double& pr,
                                          const SatID& sat);

        virtual void rotateEarth(double dt, Xvt& svPosVel);


         /// Return a string identifying this object.
        virtual std::string getClassName(void) const;


         /// Destructor.
        virtual ~ComputeSatPos() {};


    protected:


         /// Pointer to XvtStore<SatID> object
        XvtStore<SatID>* pEphStore;

         /// Default observable to be used
        TypeID defaultObsOfGPS;
        TypeID defaultObsOfGAL;
        TypeID defaultObsOfBDS;


         /// Whether the TGD effect will be applied to C1 observable or not.
        bool useTGDOfGPS;
        bool useTGDOfGAL;
        bool useTGDOfBDS;

    }; // End of class 'ComputeSatPos'

      //@}

}  // End of namespace gpstk

#endif   // ComputeSatPos_HPP
